#include "stm32f10x.h"
#include "uart.h"
#include "stdio.h"
#include "led.h"
#include "delay.h"
#include "lcd.h"
#include "24cxx.h"
#include "touch.h"
#include "timer.h"
#include "systick.h"

#include "lvgl.h"
#include "lv_port_disp.h"
#include "lv_port_indev.h"

#include "FreeRTOS.h"
#include "task.h"
#include "timers.h"
#include "semphr.h"

#include "main_ui.h"
#include <stdint.h>

#ifdef RTT_DEBUG
#include "SEGGER_RTT.h"
#endif

#include <cm_backtrace.h>

void startTask(void* args);        /* 启动任务执行函数 */
#define START_TASK_NAME "start"    /* 启动任务的名称 */
#define START_TASK_STACK_DEPTH 128 /* 启动任务栈大小 = 2 * 128 字节 */
#define START_TASK_PRIORITY 4      /* 启动任务优先级 */
TaskHandle_t startTaskTCB;         /* 启动任务的控制块 */
 

void LvglHandlerTask(void* args);
#define LVGL_TASK "lvgl task"
#define LVGL_TASK_STACK_DEPTH (512/2)
#define LVGL_TASK_PRIORITY 7
TaskHandle_t lvglTaskTCB;

void uiTask(void* args);
#define UI_TASK "ui task"
#define UI_TASK_STACK_DEPTH (1024)
#define UI_TASK_PRIORITY 6
TaskHandle_t uiTaskTCB;

void sysTask(void* args);
#define SYS_TASK "system task"
#define SYS_TASK_STACK_DEPTH (100)
#define SYS_TASK_PRIORITY 5
TaskHandle_t sysTaskTCB;



void reset_status(void)
{
    uint32_t reset_cause = RCC->CSR;
    if (reset_cause & RCC_CSR_PORRSTF)  printf("Power-on Reset\n");
    if (reset_cause & RCC_CSR_IWDGRSTF) printf("Independent Watchdog Reset\n");
    if (reset_cause & RCC_CSR_WWDGRSTF) printf("Window Watchdog Reset\n");
    if (reset_cause & RCC_CSR_SFTRSTF)  printf("Software Reset\n");
    if (reset_cause & RCC_CSR_PINRSTF)  printf("External Pin Reset\n");
    RCC->CSR |= RCC_CSR_RMVF; // 清除复位标志
}

void fault_test_by_div0(void) {
    volatile int * SCB_CCR = (volatile int *) 0xE000ED14; // SCB->CCR
    int x, y, z;

    *SCB_CCR |= (1 << 4); /* bit4: DIV_0_TRP. */

    x = 10;
    y = 0;
    z = x / y;
    printf("z:%d\n", z);
}

#define STM32_FLASH_BASE 0x08000000
#define IAP_FLASH_SIZE  0x3000
void IAP_Init(void)
{
#if (USE_BKP_SAVE_FLAG == 1)
	RCC_APB1PeriphClockCmd(RCC_APB1ENR_PWREN | RCC_APB1ENR_BKPEN , ENABLE); 
#endif
	NVIC_SetVectorTable(STM32_FLASH_BASE, IAP_FLASH_SIZE);
}


int main()
{
	IAP_Init();

#ifdef RTT_DEBUG
	SEGGER_RTT_Init();
	printf("stm32-%s-%s\n",HARDWARE_VERSION,SOFTWARE_VERSION);
#endif
	cm_backtrace_init("stm32", HARDWARE_VERSION, SOFTWARE_VERSION);
    SysTick_Init();
    uart_init(115200);
    LED_Init();
    reset_status();
    LCD_Init();
    LCD_Scan_Dir(5);
    tp_dev.init();
    tim3Init(72, 1000);

    lv_init();
    lv_port_disp_init();
    lv_port_indev_init();

    printf("start+++\n");
    xTaskCreate(startTask, START_TASK_NAME, START_TASK_STACK_DEPTH, NULL,
        START_TASK_PRIORITY, &startTaskTCB);

    vTaskStartScheduler();


    printf("start---\n");

}

void vApplicationIdleHook(void)
{
    static TickType_t last_tick = 0;

    TickType_t cur_tick = xTaskGetTickCount();
    if(cur_tick - last_tick >= 1000) {
        last_tick = cur_tick;
        char *pcTasklist = malloc(1024);
        if (pcTasklist != NULL) {
            vTaskList(pcTasklist);
			printf("[task name]\t[run]\t[priority]\t[stack]\t[num]\n");
            printf("%s\n", pcTasklist);
            free(pcTasklist);
        } else {
            printf("Failed to allocate memory for task list\n");
        }
    }



    // UBaseType_t uxHighWaterMark = uxTaskGetStackHighWaterMark(NULL);
    // printf("Idle Task:\t%u\n", (u32)uxHighWaterMark);
    
    // uxHighWaterMark = uxTaskGetStackHighWaterMark(lvglTaskTCB);
    // printf("LVGL Task:\t%u\n", (u32)uxHighWaterMark);
        
    // uxHighWaterMark = uxTaskGetStackHighWaterMark(uiTaskTCB);
    // printf("UI Task:\t%u\n", (u32)uxHighWaterMark);
    
    // uxHighWaterMark = uxTaskGetStackHighWaterMark(sysTaskTCB);
    // printf("SYSTEM Task:\t%u\n", (u32)uxHighWaterMark);

}

void vApplicationTickHook()
{
    //	printf("%s +++\n", __func__);
}

void vApplicationStackOverflowHook(TaskHandle_t xTask, char* pcTaskName)
{
    printf("%s:%s +++\n", __func__, pcTaskName);

}


TimerHandle_t lvgl_time_handle;
SemaphoreHandle_t xMutex;

void lvgl_tick_cb(TimerHandle_t xTimer)
{

    if (xSemaphoreTake(xMutex, portMAX_DELAY) == pdTRUE) {
        lv_timer_handler();
        xSemaphoreGive(xMutex);
    }

}


void startTask(void* args)
{
    vPortEnterCritical();

    xMutex = xSemaphoreCreateMutex();

    if (xMutex == NULL) {
        printf("Failed to create mutex\n");
        return;
    }

    lvgl_time_handle = xTimerCreate("lvgl tick",
        2,
        pdTRUE,
        (void*)1,
        &lvgl_tick_cb);

    xTimerStart(lvgl_time_handle, 5);

    xTaskCreate(uiTask, UI_TASK, UI_TASK_STACK_DEPTH, NULL,
        UI_TASK_PRIORITY, &uiTaskTCB);

    xTaskCreate(sysTask, SYS_TASK, SYS_TASK_STACK_DEPTH, NULL,
        SYS_TASK_PRIORITY, &sysTaskTCB);

    xTaskCreate(LvglHandlerTask, LVGL_TASK, LVGL_TASK_STACK_DEPTH, NULL,
        LVGL_TASK_PRIORITY, &lvglTaskTCB);

    vPortExitCritical();

    vTaskDelete(NULL);
}

extern lv_coord_t last_x;
extern lv_coord_t last_y;

void LvglHandlerTask(void* args)
{
    while (1) {

        vTaskDelay(50);
    }
}



#include "task.h"
void TaskFunction(void)
{

    // 获取当前任务的栈高水位线
//    UBaseType_t highWaterMark = uxTaskGetStackHighWaterMark(NULL);

    // 计算剩余栈空间
//    UBaseType_t remainingStack = (configMINIMAL_STACK_SIZE - highWaterMark) * sizeof(StackType_t);

    // 打印栈高水位线和剩余空间
//    printf("Stack High Water Mark: %lu words\n", highWaterMark);
//    printf("Remaining Stack Space: %lu bytes\n", remainingStack);

}

void sysTask(void* args)
{
    while (1) {
        TaskFunction();
        LED0(0);
        vTaskDelay(10);
        LED0(1);
        vTaskDelay(1000);
    }
}
